package com.tally.server.service;

import com.tally.server.domain.User;
import com.tally.server.domain.UserExample;
import com.tally.server.dto.*;
import com.tally.server.exception.BusinessException;
import com.tally.server.exception.BusinessExceptionCode;
import com.tally.server.exception.ValidatorException;
import com.tally.server.mapper.UserMapper;
import com.tally.server.utils.CopyUtil;
import com.tally.server.utils.IpUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.List;
import java.util.Date;

@Service
public class UserService {
    private static final Logger logger = LoggerFactory.getLogger(UserService.class);

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private LoginService loginService;

    @Autowired
    private HttpServletRequest request;

    /**
     * 列表查询
     */
    public void list(PageDTO pageDTO) {
        PageHelper.startPage(pageDTO.getPage(), pageDTO.getSize());
        UserExample userExample = new UserExample();
        List<User> userList = userMapper.selectByExample(userExample);
        PageInfo<User> pageInfo = new PageInfo<>(userList);
        pageDTO.setTotal(pageInfo.getTotal());
        List<UserDTO> userDTOList = CopyUtil.copyList(userList, UserDTO.class);
        pageDTO.setList(userDTOList);
    }

    /**
     * 保存，id有值时更新，无值时新增
     */
    public void save(UserDTO userDTO) {
        User user = CopyUtil.copy(userDTO, User.class);
        if (StringUtils.isEmpty(userDTO.getId())) {
            this.insert(user);
        } else {
            this.update(user);
        }
    }

    /**
     * 新增
     */
    private void insert(User user) {
        Date now = new Date();
//        user.setId(UUIDUtil.getShortUUID());
        user.setRegisterTime(now);
        userMapper.insert(user);
    }

    /**
     * 更新
     */
    private void update(User user) {
        userMapper.updateByPrimaryKey(user);
    }

    public UserDTO findByEmail(String email) {
        User user = selectByEmail(email);
        return CopyUtil.copy(user,UserDTO.class);
    }

    private User selectByEmail(String email) {
        if(StringUtils.isEmpty(email)){
            return null;
        }
        UserExample userExample = new UserExample();
        userExample.createCriteria().andEmailEqualTo(email);
        List<User> userList = userMapper.selectByExample(userExample);
        if(CollectionUtils.isEmpty(userList)){
            return null;
        }
        return userList.get(0);
    }

    public UserDTO findByUserName(String userName) {
        User user = selectByUserName(userName);
        return CopyUtil.copy(user,UserDTO.class);
    }

    private User selectByUserName(String userName){
        if(StringUtils.isEmpty(userName)){
            return null;
        }
        UserExample userExample = new UserExample();
        userExample.createCriteria().andUserNameEqualTo(userName);
        List<User> userList = userMapper.selectByExample(userExample);
        if(CollectionUtils.isEmpty(userList)){
            return null;
        }
        return userList.get(0);
    }

    public void resetPassword(UserDTO userDTO) {
        User userDb = selectByEmail(userDTO.getEmail());
        if(userDb == null){
            throw new BusinessException(BusinessExceptionCode.USER_NOT_EXISTS);
        }
        User user = new User();
        user.setId(userDb.getId());
        user.setPassword(userDTO.getPassword());
        userMapper.updateByPrimaryKeySelective(user);
    }

    @Transactional
    public LoginUserDTO login(UserDTO userDTO) {
        User userDb = selectByUserName(userDTO.getUserName());
        if(userDb == null){
            logger.info("用户名【{}】不存在",userDTO.getUserName());
            throw new BusinessException(BusinessExceptionCode.LOGIN_USER_ERROR);
        }
        if(!userDb.getPassword().equals(userDTO.getPassword())){
            logger.info("密码不正确");
            throw new BusinessException(BusinessExceptionCode.LOGIN_USER_ERROR);
        }
        // 登录成功
        LoginUserDTO loginUserDTO = CopyUtil.copy(userDb,LoginUserDTO.class);

        // 设置ip，添加上次登录时间
        LoginDTO loginDTO = new LoginDTO();
        String ipAddress = IpUtil.getIpAddress(request);
        loginDTO.setUserId(loginUserDTO.getId());
        loginDTO.setIpAddr(ipAddress);
        loginDTO.setOs(userDTO.getOs());
        loginDTO.setDevice("web"); // 暂时只有web端
        String cityInfo = IpUtil.getCityInfo(ipAddress);
        String addr = IpUtil.processAddr(cityInfo);
        loginDTO.setAddr(addr);
        loginService.insert(loginDTO);

        return loginUserDTO;
    }

    public void updateSelective(UserDTO userDTO) {
        User user = CopyUtil.copy(userDTO, User.class);
        userMapper.updateByPrimaryKeySelective(user);
    }

    public void setPhoto(LoginUserDTO loginUserDTO) {
        User user = new User();
        user.setId(loginUserDTO.getId());
        user.setPhoto(loginUserDTO.getPhoto());
        userMapper.updateByPrimaryKeySelective(user);
    }

    public void modifyPassword(UserModifyDTO userModifyDTO) {
        User userDb = userMapper.selectByPrimaryKey(userModifyDTO.getUserId());
        if(!userDb.getPassword().equals(userModifyDTO.getOldPassword())){
            throw new BusinessException(BusinessExceptionCode.OLD_PASSWORD_INCORRECT);
        }
        userDb.setPassword(userModifyDTO.getNewPassword());
        update(userDb);
    }

    public String getName(Integer id){
        User user = userMapper.selectByPrimaryKey(id);
        return user.getName();
    }

    public UserDTO getById(Integer id) {
        User user = userMapper.selectByPrimaryKey(id);
        return CopyUtil.copy(user, UserDTO.class);
    }
}
